home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 18.2 KB | 599 lines | [TEXT/CWIE] |
- /*
- File: SetupGL Main Windowed.c
-
- Contains: An example of the use of the SeupGL utility code for windowed applications.
-
- Written by: Geoff Stahl
-
- Copyright: 2000 Apple Computer, Inc., All Rights Reserved
-
- Change History (most recent first):
-
-
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- ("Apple") in consideration of your agreement to the following terms, and your
- use, installation, modification or redistribution of this Apple software
- constitutes acceptance of these terms. If you do not agree with these terms,
- please do not use, install, modify or redistribute this Apple software.
-
- In consideration of your agreement to abide by the following terms, and subject
- to these terms, Apple grants you a personal, non-exclusive license, under Appleās
- copyrights in this original Apple software (the "Apple Software"), to use,
- reproduce, modify and redistribute the Apple Software, with or without
- modifications, in source and/or binary forms; provided that if you redistribute
- the Apple Software in its entirety and without modifications, you must retain
- this notice and the following text and disclaimers in all such redistributions of
- the Apple Software. Neither the name, trademarks, service marks or logos of
- Apple Computer, Inc. may be used to endorse or promote products derived from the
- Apple Software without specific prior written permission from Apple. Except as
- expressly stated in this notice, no other rights or licenses, express or implied,
- are granted by Apple herein, including but not limited to any patent rights that
- may be infringed by your derivative works or by other works in which the Apple
- Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- <1> 3/22/00 ggs New windowed demo code
- <6+> 2/24/00 ggs Windowed mode support
- <6> 1/26/00 ggs Add preflight support, handle failure conditions throughout app
- better
- <5> 1/24/00 ggs fixed Apple menu selection, fixed aglfont texture row length
- problem, fixed suspend/resume, fixed update
- <4> 12/18/99 ggs Fix headers
- <3> 12/18/99 ggs Added window/fullscreen toggle support and error window
- <2> 11/28/99 ggs Standard toolbox application
- <1> 11/28/99 ggs Initial Add
- <6> 9/14/99 GGS Corrected buffer rect handling and cleaned up code
- <5> 7/14/99 GGS Fixed multi-monitor window centering
- <4> 7/13/99 GGS Add work around for over zealous checking in single buffer DSp context attributes
- <3> 7/5/99 GGS Now correctly handle multi-monitor (DSp front buffer for single device; Window on top of context for multiple devices)
- <2> 5/28/99 GGS Added better multi-monitor support, clean code, corrected blanking bug, added timing, correct pixel formats
- <1> ? ? Initial build
- */
-
-
- // system includes ----------------------------------------------------------
-
- #include <Devices.h>
- #include <Dialogs.h>
- #include <DriverServices.h>
- #include <Events.h>
- #include <LowMem.h>
- #include <TextEdit.h>
- #include <ToolUtils.h>
- #include <Windows.h>
-
- #include <math.h>
- #include <stdio.h>
- #include <string.h>
-
- #include <gl.h>
-
- // project includes ---------------------------------------------------------
-
- #include "SetupGL.h"
-
- // prototypes ---------------------------------------------------------------
-
- void InitToolbox(void);
- Boolean SetUp (void);
- void DoMenu (SInt32 menuResult);
- void DoKey (SInt8 theKey, SInt8 theCode);
- void DoUpdate (WindowPtr pWindow);
- void DoEvent (void);
- void CleanUp (void);
-
- void drawGL(WindowPtr pWindow, AGLContext aglContext, GLuint fontList);
-
- void DrawFrameRate (GLuint fontList);
- void DrawContextInfo (GLuint fontList);
-
- void DrawPStringGL (Str255 pstrOut, GLuint fontList);
- void DrawCStringGL (char * cstrOut, GLuint fontList);
- GLuint BuildFontGL (AGLContext ctx, GLint fontID, Style face, GLint size);
- void DeleteFontGL (GLuint fontList);
-
-
- // statics/globals (internal only) ------------------------------------------
-
- // Menu defs
- enum
- {
- kNumRes = 10,
- kNumFreqs = 11,
-
- kMenuApple = 128,
- kMenuFile = 129,
-
- kAppleAbout = 1,
- kFileQuit = 1
- };
-
- enum
- {
- kForegroundSleep = 0,
- kBackgroundSleep = 10
- };
-
- const RGBColor rgbWhite = { 0xFFFF, 0xFFFF, 0xFFFF };
-
- SInt32 gSleepTime = kForegroundSleep;
- Boolean gDone = false, gfFrontProcess = true;
-
- char gstrContext1 [256] = ""; // mode strings
- char gstrContext2 [256] = "";
-
- structGLWindowInfo glInfo1, glInfo2;
- AGLContext aglContext1 = 0, aglContext2 = 0;
- GLuint gFontList1 = 0, gFontList2 = 0;
-
- WindowPtr gpWindow1 = NULL, gpWindow2 = NULL;
-
-
- // functions (internal/private) ---------------------------------------------
-
- void InitToolbox(void)
- {
- MenuHandle menu;
-
- MaxApplZone ();
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- qd.randSeed = TickCount();
-
- // Init Menus
- menu = NewMenu (kMenuApple, "\p\024"); // new apple menu
- InsertMenu (menu, 0); // add menu to end
- AppendResMenu(menu, 'DRVR');
-
- menu = NewMenu (kMenuFile, "\pFile"); // new menu
- InsertMenu (menu, 0); // add menu to end
- AppendMenu (menu, "\pQuit/Q"); // add items
-
- DrawMenuBar();
- }
-
- // --------------------------------------------------------------------------
-
- Boolean SetUp (void)
- {
- short i;
- short fNum;
-
- InitToolbox ();
-
- if (PreflightGL (false))
- {
- Rect rectWin1 = {100, 100, 500, 500}, rectWin2 = {300, 350, 600, 650};
-
- memset(&glInfo1, 0, sizeof glInfo1);
- glInfo1.fAcceleratedMust = true; // must renderer be accelerated?
- glInfo1.VRAM = 0 * 1048576; // minimum VRAM (if not zero this is always required)
- glInfo1.textureRAM = 0 * 1048576; // minimum texture RAM (if not zero this is always required)
- glInfo1.fDraggable = false; // desired vertical refresh frquency in Hz (0 = any)
- glInfo1.fmt = 0; // output pixel format
-
- i = 0;
- glInfo1.aglAttributes [i++] = AGL_RGBA;
- glInfo1.aglAttributes [i++] = AGL_DOUBLEBUFFER;
- glInfo1.aglAttributes [i++] = AGL_ACCELERATED;
- glInfo1.aglAttributes [i++] = AGL_DEPTH_SIZE;
- glInfo1.aglAttributes [i++] = 16;
- glInfo1.aglAttributes [i++] = AGL_NONE;
- gpWindow1 = (WindowPtr) NewCWindow (NULL, &rectWin1, "\pWindow 1", true, kWindowPlainDialogProc, (WindowPtr)-1, 0, 0);
- BuildGLFromWindow ((CGrafPtr) gpWindow1, &aglContext1, &glInfo1);
- if (!aglContext1)
- {
- DestroyGLFromWindow (&aglContext1, &glInfo1);
- sprintf (gstrContext1, "No context");
- }
- else// set mode string
- sprintf (gstrContext1, "%d x %d", gpWindow1->portRect.right - gpWindow1->portRect.left, gpWindow1->portRect.bottom - gpWindow1->portRect.top);
-
- memset(&glInfo2, 0, sizeof glInfo2);
- glInfo2.fAcceleratedMust = true; // must renderer be accelerated?
- glInfo2.VRAM = 0 * 1048576; // minimum VRAM (if not zero this is always required)
- glInfo2.textureRAM = 0 * 1048576; // minimum texture RAM (if not zero this is always required)
- glInfo2.fDraggable = true; // desired vertical refresh frquency in Hz (0 = any)
- glInfo2.fmt = 0; // output pixel format
-
- i = 0;
- glInfo2.aglAttributes [i++] = AGL_RGBA;
- glInfo2.aglAttributes [i++] = AGL_DOUBLEBUFFER;
- // glInfo2.aglAttributes [i++] = AGL_ACCELERATED; // can't use this for dragable windows
- glInfo2.aglAttributes [i++] = AGL_DEPTH_SIZE;
- glInfo2.aglAttributes [i++] = 16;
- glInfo2.aglAttributes [i++] = AGL_NONE;
- gpWindow2 = (WindowPtr) NewCWindow (NULL, &rectWin2, "\pWindow 2", true, kWindowFloatGrowProc, (WindowPtr)-1, 0, 0);
- BuildGLFromWindow ((CGrafPtr) gpWindow2, &aglContext2, &glInfo2);
- if (!aglContext2)
- {
- DestroyGLFromWindow (&aglContext2, &glInfo2);
- sprintf (gstrContext2, "No context");
- }
- else// set mode string
- sprintf (gstrContext2, "%d x %d", gpWindow2->portRect.right - gpWindow2->portRect.left, gpWindow2->portRect.bottom - gpWindow2->portRect.top);
- }
-
- GetFNum("\pMonaco", &fNum); // build font
- if (aglContext1)
- gFontList1 = BuildFontGL (aglContext1, fNum, normal, 9);
- GetFNum("\pGeneva", &fNum); // build font
- if (aglContext2)
- gFontList2 = BuildFontGL (aglContext2, fNum, italic, 9);
- return true;
- }
-
- // --------------------------------------------------------------------------
-
- void DoMenu (SInt32 menuResult)
- {
- SInt16 theMenu;
- SInt16 theItem;
- Str255 daName;
- MenuRef theMenuHandle;
-
- theMenu = HiWord(menuResult);
- theItem = LoWord(menuResult);
- theMenuHandle = GetMenuHandle(theMenu);
-
- switch (theMenu)
- {
- case kMenuApple:
- switch (theItem)
- {
- case kAppleAbout:
- break;
- default:
- GetMenuItemText (theMenuHandle, theItem, daName);
- OpenDeskAcc(daName);
- break;
- }
- break;
- case kMenuFile:
- switch (theItem)
- {
- case kFileQuit:
- gDone = true;
- break;
- }
- break;
- }
- HiliteMenu(0);
- DrawMenuBar();
- }
-
- // --------------------------------------------------------------------------
-
- void DoKey (SInt8 theKey, SInt8 theCode)
- {
- #pragma unused (theCode, theKey)
- // do nothing
- }
-
- // --------------------------------------------------------------------------
-
- void DoUpdate (WindowPtr pWindow)
- {
- if ((pWindow == gpWindow1) && aglContext1)
- {
- ResumeGL ((CGrafPtr) gpWindow1, aglContext1);
- drawGL (gpWindow1, aglContext1, gFontList1);
- }
- if ((pWindow == gpWindow2) && aglContext2)
- {
- ResumeGL ((CGrafPtr) gpWindow2, aglContext2);
- drawGL (gpWindow1, aglContext2, gFontList2);
- }
- }
-
- // --------------------------------------------------------------------------
-
- void DoEvent (void)
- {
- EventRecord theEvent;
- Rect rectGrow;
- SInt32 menuResult;
- WindowRef whichWindow;
- GrafPtr pGrafSave;
- long grow;
- SInt16 whatPart;
- SInt8 theKey;
- SInt8 theCode;
- Boolean fProcessed = false;
-
- if (WaitNextEvent(everyEvent, &theEvent, gSleepTime, NULL))
- {
- {
- switch (theEvent.what)
- {
- case mouseDown:
- whatPart = FindWindow(theEvent.where, &whichWindow);
- SelectWindow (whichWindow);
- switch (whatPart)
- {
- case inGoAway:
- break;
- case inMenuBar:
- DrawMenuBar();
- menuResult = MenuSelect(theEvent.where);
- if (HiWord(menuResult) != 0)
- DoMenu(menuResult);
- break;
- case inDrag:
- if (gpWindow2 == whichWindow)
- DragWindow (whichWindow, theEvent.where, &(**LMGetGrayRgn()).rgnBBox);
- // must reset the drawable just incase we moved renderers
- aglSetDrawable(aglContext2, (CGrafPtr) NULL);
- aglSetDrawable(aglContext2, (CGrafPtr) gpWindow2);
- break;
- case inGrow:
- SetRect (&rectGrow, 100, 100, 20000, 20000);
- grow = GrowWindow (whichWindow, theEvent.where, &rectGrow);
- if (grow)
- {
- SizeWindow (whichWindow, grow & 0x0000FFFF, grow >> 16, true);
- // do content stuff here
- SetPort (whichWindow);
- InvalRect (&whichWindow->portRect); // redraw all
- if ((whichWindow == gpWindow2) && aglContext2)
- {
- aglSetDrawable(aglContext2, (CGrafPtr) NULL);
- aglSetDrawable(aglContext2, (CGrafPtr) gpWindow2);
- sprintf (gstrContext2, "%d x %d", gpWindow2->portRect.right - gpWindow2->portRect.left, gpWindow2->portRect.bottom - gpWindow2->portRect.top);
- }
- if ((whichWindow == gpWindow1) && aglContext1)
- {
- aglSetDrawable(aglContext1, (CGrafPtr) NULL);
- aglSetDrawable(aglContext1, (CGrafPtr) gpWindow1);
- sprintf (gstrContext1, "%d x %d", gpWindow1->portRect.right - gpWindow1->portRect.left, gpWindow1->portRect.bottom - gpWindow1->portRect.top);
- }
-
- }
- break;
- case inSysWindow:
- SystemClick(&theEvent, whichWindow);
- break;
- }
- break;
- case keyDown:
- case autoKey:
- theKey = theEvent.message & charCodeMask;
- theCode = (theEvent.message & keyCodeMask) >> 8;
- if ((theEvent.modifiers & cmdKey) != 0)
- {
- menuResult = MenuKey(theKey);
- if (HiWord(menuResult) != 0)
- DoMenu (menuResult);
- }
- else
- DoKey (theKey, theCode);
- break;
- case updateEvt:
- whichWindow = (WindowRef) theEvent.message;
- GetPort (&pGrafSave);
- SetPort ((GrafPtr) whichWindow);
- BeginUpdate(whichWindow);
- DoUpdate(whichWindow);
- SetPort ((GrafPtr) whichWindow);
- EndUpdate(whichWindow);
- SetPort (pGrafSave);
- break;
- case diskEvt:
- break;
- case osEvt:
- if (theEvent.message & 0x01000000) // Suspend/resume event
- {
- if (theEvent.message & 0x00000001) // Resume
- {
-
- gSleepTime = kForegroundSleep;
- if (gpWindow1 && aglContext1)
- DoUpdate (gpWindow1);
- if (gpWindow2 && aglContext2)
- DoUpdate (gpWindow2);
- gfFrontProcess = true;
- }
- else
- {
- gSleepTime = kBackgroundSleep; // Suspend
- gfFrontProcess = false;
- }
- }
- break;
-
- case kHighLevelEvent:
- AEProcessAppleEvent(&theEvent);
- break;
- }
- }
- }
- else
- {
- DoUpdate (gpWindow1);
- DoUpdate (gpWindow2);
- }
- }
-
- // --------------------------------------------------------------------------
-
- void CleanUp (void)
- {
- MenuHandle hMenu;
-
- DeleteFontGL (gFontList1);
- DeleteFontGL (gFontList2);
- DestroyGLFromWindow (&aglContext1, &glInfo1);
- DestroyGLFromWindow (&aglContext2, &glInfo2);
-
- if (gpWindow1)
- {
- DisposeWindow ((WindowPtr)gpWindow1);
- gpWindow1 = NULL;
- }
- if (gpWindow2)
- {
- DisposeWindow ((WindowPtr)gpWindow2);
- gpWindow2 = NULL;
- }
-
- hMenu = GetMenuHandle (kMenuFile);
- DeleteMenu (kMenuFile);
- DisposeMenu (hMenu);
-
- hMenu = GetMenuHandle (kMenuApple);
- DeleteMenu (kMenuApple);
- DisposeMenu (hMenu);
- }
-
- // --------------------------------------------------------------------------
-
- int main (void)
- {
- if (SetUp ())
- while (!gDone)
- DoEvent ();
- CleanUp ();
- return 0;
- }
-
-
- #pragma mark -
- //-----------------------------------------------------------------------------------------------------------------------
-
- // OpenGL Drawing
-
- void drawGL(WindowPtr pWindow, AGLContext aglContext, GLuint fontList)
- {
- static float f, s, c;
- GLboolean fState = GL_FALSE;
-
- f += 0.01;
- s = sin(f);
- c = cos(f);
-
- glClearColor(0.15f, 0.15f, 0.15f, 1.0f); // Clear color buffer to dark grey
- glClear(GL_COLOR_BUFFER_BIT);
-
- glBegin(GL_POLYGON); // Draw a smooth shaded polygon
- glColor3d(1.0, 0.0, 0.0);
- glVertex3d(s, c, 0.0);
- glColor3d(0.0, 1.0, 0.0);
- glVertex3d(-c, s, 0.0);
- glColor3d(0.0, 0.0, 1.0);
- glVertex3d(-s, -c, 0.0);
- glColor3d(0.7, 0.7, 0.7);
- glVertex3d(c, -s, 0.0);
- glEnd();
-
- // Draw frame rate (set color and position first)
- glColor3d(1.0, 1.0, 1.0);
- glRasterPos3d (-0.95, ((pWindow->portRect.bottom - pWindow->portRect.top) - 40.0) / (float) (pWindow->portRect.bottom - pWindow->portRect.top), 0.0);
- DrawFrameRate (fontList);
- glRasterPos3d (-0.95, ((pWindow->portRect.bottom - pWindow->portRect.top) - 65.0) / (float) (pWindow->portRect.bottom - pWindow->portRect.top), 0.0);
- if (aglContext == aglContext1)
- DrawCStringGL (gstrContext1, fontList);
- else
- DrawCStringGL (gstrContext2, fontList);
-
-
- glRasterPos3d (-0.95, -((pWindow->portRect.bottom - pWindow->portRect.top) - 45.0) / (float) (pWindow->portRect.bottom - pWindow->portRect.top), 0.0);
- DrawCStringGL ((char*) glGetString (GL_VENDOR), fontList);
- glRasterPos3d (-0.95, -((pWindow->portRect.bottom - pWindow->portRect.top) - 20.0) / (float) (pWindow->portRect.bottom - pWindow->portRect.top), 0.0);
- DrawCStringGL ((char*) glGetString (GL_RENDERER), fontList);
-
- aglSwapBuffers(aglContext); // send swap command
- }
-
- //-----------------------------------------------------------------------------------------------------------------------
-
- // Draw frame rate in curent color at current raster positon with provided font display list
-
- void DrawFrameRate (GLuint fontList)
- {
- static char aChar[256] = "";
- static AbsoluteTime time = {0,0};
- static long frames = 0;
-
- AbsoluteTime currTime = UpTime ();
- float deltaTime = (float) AbsoluteDeltaToDuration (currTime, time);
-
- frames++;
-
- if (0 > deltaTime) // if negative microseconds
- deltaTime /= -1000000.0;
- else // else milliseconds
- deltaTime /= 1000.0;
- if (0.5 <= deltaTime) // has update interval passed
- {
- sprintf (aChar, "Swaps/Sec: %0.1f", frames / deltaTime);
- time = currTime; // reset for next time interval
- frames = 0;
- }
-
- DrawCStringGL (aChar, fontList);
- }
-
- #pragma mark -
- //-----------------------------------------------------------------------------------------------------------------------
-
- void DrawPStringGL (Str255 pstrOut, GLuint fontList)
- {
- GLint i;
- for (i = 1; i <= pstrOut[0]; i++)
- glCallList (fontList + pstrOut[i]);
- }
-
- //-----------------------------------------------------------------------------------------------------------------------
-
- void DrawCStringGL (char * cstrOut, GLuint fontList)
- {
- GLint i = 0;
- while (cstrOut [i])
- glCallList (fontList + cstrOut[i++]);
- }
-
- //-----------------------------------------------------------------------------------------------------------------------
-
- GLuint BuildFontGL (AGLContext ctx, GLint fontID, Style face, GLint size)
- {
- GLuint listBase = glGenLists (256);
- if (aglUseFont (ctx, fontID , face, size, 0, 256, (long) listBase))
- {
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- return listBase;
- }
- else
- {
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glDeleteLists (listBase, 256);
- return 0;
- }
- }
-
- //-----------------------------------------------------------------------------------------------------------------------
-
- void DeleteFontGL (GLuint fontList)
- {
- if (fontList)
- glDeleteLists (fontList, 256);
- }